package main

import (
	"bytes"
	"fmt"
	"io"
	"strings"
)

func test1() {
	// strings.Builder类型实现的io包中的接口
	builder := new(strings.Builder)
	_ = interface{}(builder).(io.Writer)
	_ = interface{}(builder).(io.ByteWriter)
	_ = interface{}(builder).(fmt.Stringer)

	// strings.Reader类型实现的io包中的接口
	reader := strings.NewReader("")
	_ = interface{}(reader).(io.Reader)
	_ = interface{}(reader).(io.ReaderAt)
	_ = interface{}(reader).(io.ByteReader)
	_ = interface{}(reader).(io.RuneReader)
	_ = interface{}(reader).(io.Seeker)
	_ = interface{}(reader).(io.ByteScanner)
	_ = interface{}(reader).(io.RuneScanner)
	_ = interface{}(reader).(io.WriterTo)

	// bytes.Buffer类型实现的io包中的接口
	buffer := bytes.NewBuffer([]byte{})
	_ = interface{}(buffer).(io.Reader)
	_ = interface{}(buffer).(io.ByteReader)
	_ = interface{}(buffer).(io.RuneReader)
	_ = interface{}(buffer).(io.ByteScanner)
	_ = interface{}(buffer).(io.RuneScanner)
	_ = interface{}(buffer).(io.WriterTo)
	_ = interface{}(buffer).(io.Writer)
	_ = interface{}(buffer).(io.ByteWriter)
	_ = interface{}(buffer).(io.ReaderFrom)
	_ = interface{}(buffer).(fmt.Stringer)
}
func test2() {
	//使用strings.NewReader创建了一个字符串读取器，并赋给了变量src
	src := strings.NewReader("Go语言标准库常用的代码包")
	//new一个字符串构建器，并将其赋予了变量dst
	dst := new(strings.Builder)
	//调用io.CopyN函数，把这两个变量的值都传进去，从src中拷贝前8个字节到dst那里。
	written, err := io.CopyN(dst, src, 8)
	if err != nil {
		fmt.Printf("error: %v\n", err)
	} else {
		fmt.Printf("Written(%d): %q\n", written, dst.String()) //Written(8): "Go语言"
	}
}
func test3() {
	comment := "hello and thank you"
	// 示例1
	reader1 := strings.NewReader(comment)
	buf1 := make([]byte, 7)
	n, err := reader1.Read(buf1)
	var offset1, index1 int64
	executeIfNoErr(err, func() {
		fmt.Printf("Read(%d): %q\n", n, buf1[:n]) //Read(7): "hello a"
		offset1 = int64(3)
		index1, err = reader1.Seek(offset1, io.SeekCurrent)
	})
	executeIfNoErr(err, func() {
		fmt.Printf("%d: %d\n", offset1, index1) //3: 10
		n, err = reader1.Read(buf1)
	})
	executeIfNoErr(err, func() {
		fmt.Printf("Read(%d): %q\n", n, buf1[:n]) //Read(7): "thank y"
	})
	fmt.Println()

	// 示例2
	reader1.Reset(comment)
	num1 := int64(7)
	fmt.Printf("%d \n", num1) //7
	reader2 := io.LimitReader(reader1, 7)
	buf2 := make([]byte, 2)
	for i := 0; i < 3; i++ {
		n, err = reader2.Read(buf2)
		executeIfNoErr(err, func() {
			fmt.Printf("Read(%d): %q\n", n, buf2[:n])
		})
	}
	/*
		Read(2): "he"
		Read(2): "ll"
		Read(2): "o "
	*/
	fmt.Println()

	// 示例3
	reader1.Reset(comment)
	offset2 := int64(3)
	num2 := int64(9)
	reader3 := io.NewSectionReader(reader1, offset2, num2)
	buf3 := make([]byte, 1)
	for i := 0; i < 5; i++ {
		n, err = reader3.Read(buf3)
		executeIfNoErr(err, func() {
			fmt.Printf("Read(%d): %q\n", n, buf3[:n])
		})
	}
	/*
		Read(1): "l"
		Read(1): "o"
		Read(1): " "
		Read(1): "a"
		Read(1): "n"
	*/
	fmt.Println()

	// 示例4
	reader1.Reset(comment)
	writer1 := new(strings.Builder)
	reader4 := io.TeeReader(reader1, writer1)
	buf4 := make([]byte, 4)
	for i := 0; i < 5; i++ {
		n, err = reader4.Read(buf4)
		executeIfNoErr(err, func() {
			fmt.Printf("Read(%d): %q\n", n, buf4[:n])
		})
	}
	/*
		Read(4): "hell"
		Read(4): "o an"
		Read(4): "d th"
		Read(4): "ank "
		Read(3): "you"
	*/
	fmt.Println()

	// 示例5
	reader5a := strings.NewReader("One")
	reader5b := strings.NewReader("Two")
	reader5c := strings.NewReader("Three")
	reader5d := strings.NewReader("Four")
	reader5 := io.MultiReader(reader5a, reader5b, reader5c, reader5d)
	buf5 := make([]byte, 3)
	for i := 0; i < 7; i++ {
		n, err = reader5.Read(buf5)
		executeIfNoErr(err, func() {
			fmt.Printf("Read(%d): %q\n", n, buf5[:n])
		})
	}
	/*
		Read(3): "One"
		Read(3): "Two"
		Read(3): "Thr"
		Read(2): "ee"
		Read(3): "Fou"
		Read(1): "r"
		error: EOF
	*/
	fmt.Println()
}
func executeIfNoErr(err error, f func()) {
	if err != nil {
		fmt.Printf("error: %v\n", err)
		return
	}
	f()
}

func test4() {
	comment := "this is a long long text,because i will use it to test something ..."
	basicReader := strings.NewReader(comment)
	basicWriter := new(strings.Builder)

	// 示例1。
	reader1 := io.LimitReader(basicReader, 98)
	_ = interface{}(reader1).(io.Reader)

	// 示例2。
	reader2 := io.NewSectionReader(basicReader, 98, 89)
	_ = interface{}(reader2).(io.Reader)
	_ = interface{}(reader2).(io.ReaderAt)
	_ = interface{}(reader2).(io.Seeker)

	// 示例3。
	reader3 := io.TeeReader(basicReader, basicWriter)
	_ = interface{}(reader3).(io.Reader)

	// 示例4。
	reader4 := io.MultiReader(reader1)
	_ = interface{}(reader4).(io.Reader)

	// 示例5。
	writer1 := io.MultiWriter(basicWriter)
	_ = interface{}(writer1).(io.Writer)

	// 示例6。
	pReader, pWriter := io.Pipe()
	_ = interface{}(pReader).(io.Reader)
	_ = interface{}(pReader).(io.Closer)
	_ = interface{}(pWriter).(io.Writer)
	_ = interface{}(pWriter).(io.Closer)
}
func main() {
	test1()
	test2()
	test3()
	test4()
}
